From 19b34a44b232d6b86700382ade1daced9d601a60 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 3 Nov 2015 12:20:53 -0500 Subject: [PATCH] model button: Complete the CSS node conversion There was still style context saving in the draw function, and the CSS node was not always properly updated and positioned. Fix these things, and use the same CSS node for the arrow drawing as well. --- gtk/gtkmodelbutton.c | 138 +++++++++++++++++++++++++++++++------------ 1 file changed, 100 insertions(+), 38 deletions(-) diff --git a/gtk/gtkmodelbutton.c b/gtk/gtkmodelbutton.c index d3c791647d..e65cc80418 100644 --- a/gtk/gtkmodelbutton.c +++ b/gtk/gtkmodelbutton.c @@ -143,24 +143,70 @@ enum static GParamSpec *properties[LAST_PROPERTY] = { NULL, }; +static gboolean +indicator_is_left (GtkWidget *widget) +{ + GtkModelButton *button = GTK_MODEL_BUTTON (widget); + + return ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL && !button->inverted) || + (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR && button->inverted)); +} + static void gtk_model_button_update_state (GtkModelButton *button) { GtkStateFlags state; - if (button->role == GTK_BUTTON_ROLE_NORMAL) - return; - state = gtk_widget_get_state_flags (GTK_WIDGET (button)); - state &= ~GTK_STATE_FLAG_CHECKED; + if (button->role == GTK_BUTTON_ROLE_CHECK || + button->role == GTK_BUTTON_ROLE_RADIO) + { + state &= ~GTK_STATE_FLAG_CHECKED; - if (button->active && !button->menu_name) - state |= GTK_STATE_FLAG_CHECKED; + if (button->active && !button->menu_name) + state |= GTK_STATE_FLAG_CHECKED; + } + + if (button->menu_name) + { + state = state & ~(GTK_STATE_FLAG_DIR_LTR|GTK_STATE_FLAG_DIR_RTL); + if (indicator_is_left (GTK_WIDGET (button))) + state = state | GTK_STATE_FLAG_DIR_RTL; + else + state = state | GTK_STATE_FLAG_DIR_LTR; + } gtk_css_node_set_state (button->indicator_node, state); } +static void +update_node_ordering (GtkModelButton *button) +{ + GtkCssNode *widget_node, *node; + + widget_node = gtk_widget_get_css_node (GTK_WIDGET (button)); + + if (indicator_is_left (GTK_WIDGET (button))) + { + gtk_css_node_add_class (button->indicator_node, g_quark_from_static_string (GTK_STYLE_CLASS_LEFT)); + gtk_css_node_remove_class (button->indicator_node, g_quark_from_static_string (GTK_STYLE_CLASS_RIGHT)); + + node = gtk_css_node_get_first_child (widget_node); + if (node != button->indicator_node) + gtk_css_node_insert_before (widget_node, button->indicator_node, node); + } + else + { + gtk_css_node_remove_class (button->indicator_node, g_quark_from_static_string (GTK_STYLE_CLASS_LEFT)); + gtk_css_node_add_class (button->indicator_node, g_quark_from_static_string (GTK_STYLE_CLASS_RIGHT)); + + node = gtk_css_node_get_last_child (widget_node); + if (node != button->indicator_node) + gtk_css_node_insert_after (widget_node, button->indicator_node, node); + } +} + static void gtk_model_button_state_flags_changed (GtkWidget *widget, GtkStateFlags previous_flags) @@ -169,26 +215,40 @@ gtk_model_button_state_flags_changed (GtkWidget *widget, } static void -gtk_model_button_set_role (GtkModelButton *button, - GtkButtonRole role) +gtk_model_button_direction_changed (GtkWidget *widget, + GtkTextDirection previous_dir) +{ + GtkModelButton *button = GTK_MODEL_BUTTON (widget); + + gtk_model_button_update_state (button); + update_node_ordering (button); + + GTK_WIDGET_CLASS (gtk_model_button_parent_class)->direction_changed (widget, previous_dir); +} + +static void +update_node_name (GtkModelButton *button) { AtkObject *accessible; AtkRole a11y_role; const gchar *name; gboolean visible; - if (role == button->role) - return; - - button->role = role; - accessible = gtk_widget_get_accessible (GTK_WIDGET (button)); - switch (role) + switch (button->role) { case GTK_BUTTON_ROLE_NORMAL: a11y_role = ATK_ROLE_PUSH_BUTTON; - name = I_("check"); - visible = FALSE; + if (button->menu_name) + { + name = I_("arrow"); + visible = TRUE; + } + else + { + name = I_("check"); + visible = FALSE; + } break; case GTK_BUTTON_ROLE_CHECK: @@ -210,6 +270,18 @@ gtk_model_button_set_role (GtkModelButton *button, atk_object_set_role (accessible, a11y_role); gtk_css_node_set_name (button->indicator_node, name); gtk_css_node_set_visible (button->indicator_node, visible); +} + +static void +gtk_model_button_set_role (GtkModelButton *button, + GtkButtonRole role) +{ + if (role == button->role) + return; + + button->role = role; + + update_node_name (button); gtk_model_button_update_state (button); gtk_widget_queue_draw (GTK_WIDGET (button)); @@ -266,7 +338,15 @@ gtk_model_button_set_menu_name (GtkModelButton *button, { g_free (button->menu_name); button->menu_name = g_strdup (menu_name); + + update_node_name (button); gtk_model_button_update_state (button); + + if (menu_name) + gtk_css_node_add_class (button->indicator_node, g_quark_from_static_string (GTK_STYLE_CLASS_EXPANDER)); + else + gtk_css_node_remove_class (button->indicator_node, g_quark_from_static_string (GTK_STYLE_CLASS_EXPANDER)); + gtk_widget_queue_resize (GTK_WIDGET (button)); g_object_notify_by_pspec (G_OBJECT (button), properties[PROP_MENU_NAME]); } @@ -279,6 +359,8 @@ gtk_model_button_set_inverted (GtkModelButton *button, return; button->inverted = inverted; + gtk_model_button_update_state (button); + update_node_ordering (button); gtk_widget_queue_resize (GTK_WIDGET (button)); g_object_notify_by_pspec (G_OBJECT (button), properties[PROP_INVERTED]); } @@ -647,16 +729,6 @@ gtk_model_button_get_preferred_height (GtkWidget *widget, NULL, NULL); } -static gboolean -indicator_is_left (GtkWidget *widget) -{ - GtkModelButton *button = GTK_MODEL_BUTTON (widget); - - return ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL && !button->inverted) || - (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR && button->inverted)); - -} - static void gtk_model_button_size_allocate (GtkWidget *widget, GtkAllocation *allocation) @@ -764,18 +836,7 @@ gtk_model_button_draw (GtkWidget *widget, if (model_button->menu_name) { - GtkStateFlags state; - - gtk_style_context_save_named (context, "arrow"); - state = gtk_style_context_get_state (context); - state = state & ~(GTK_STATE_FLAG_DIR_LTR|GTK_STATE_FLAG_DIR_RTL); - if (indicator_is_left (widget)) - state = state | GTK_STATE_FLAG_DIR_RTL; - else - state = state | GTK_STATE_FLAG_DIR_LTR; - - gtk_style_context_set_state (context, state); - gtk_style_context_add_class (context, GTK_STYLE_CLASS_EXPANDER); + gtk_style_context_save_to_node (context, model_button->indicator_node); gtk_render_expander (context, cr, x, y, indicator_size, indicator_size); gtk_style_context_restore (context); } @@ -863,6 +924,7 @@ gtk_model_button_class_init (GtkModelButtonClass *class) widget_class->draw = gtk_model_button_draw; widget_class->destroy = gtk_model_button_destroy; widget_class->state_flags_changed = gtk_model_button_state_flags_changed; + widget_class->direction_changed = gtk_model_button_direction_changed; button_class->clicked = gtk_model_button_clicked; -- 2.30.2